package com.ruoyi.web.controller.mbti;

import java.util.List;
import java.util.Map;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.system.domain.MbtiTestType;
import com.ruoyi.system.domain.MbtiResult;
import com.ruoyi.system.domain.MbtiPersonalityType;
import com.ruoyi.system.service.IMbtiTestService;

/**
 * MBTI测试Controller
 * 
 * @author ruoyi
 * @date 2025-01-21
 */
@RestController
@RequestMapping("/mbti/test")
public class MbtiTestController extends BaseController
{
    @Autowired
    private IMbtiTestService mbtiTestService;

    /**
     * 获取所有可用的测试类型
     */
    @GetMapping("/types")
    public AjaxResult getTestTypes()
    {
        List<MbtiTestType> testTypes = mbtiTestService.getAvailableTestTypes();
        return success(testTypes);
    }

    /**
     * 获取测试类型详情
     */
    @GetMapping("/types/{testTypeId}")
    public AjaxResult getTestTypeDetail(@PathVariable Long testTypeId)
    {
        MbtiTestType testType = mbtiTestService.getTestTypeById(testTypeId);
        if (testType == null)
        {
            return error("测试类型不存在");
        }
        return success(testType);
    }

    /**
     * 开始测试
     */
    @Log(title = "MBTI测试", businessType = BusinessType.INSERT)
    @PostMapping("/start")
    public AjaxResult startTest(@RequestBody Map<String, Object> params, HttpServletRequest request)
    {
        Long testTypeId = Long.valueOf(params.get("testTypeId").toString());
        String userName = (String) params.get("userName");
        String userEmail = (String) params.get("userEmail");
        
        // 获取当前用户ID（如果已登录）
        Long userId = null;
        Authentication authentication = SecurityUtils.getAuthentication();
        if (authentication != null && authentication.getPrincipal() instanceof LoginUser) {
            userId = ((LoginUser) authentication.getPrincipal()).getUserId();
        }
        // 未登录用户允许匿名测试
        
        String ipAddress = IpUtils.getIpAddr(request);
        String userAgent = request.getHeader("User-Agent");
        
        Long recordId = mbtiTestService.startTest(testTypeId, userId, userName, userEmail, ipAddress, userAgent);

        // 创建返回数据
        java.util.Map<String, Object> data = new java.util.HashMap<>();
        data.put("recordId", recordId);

        return AjaxResult.success("测试开始成功", data);
    }

    /**
     * 获取测试题目列表（支持按需加载优化）
     */
    @GetMapping("/questions/{testTypeId}")
    public AjaxResult getTestQuestions(
        @PathVariable Long testTypeId,
        @RequestParam(defaultValue = "false") Boolean onlyIds,
        @RequestParam(defaultValue = "true") Boolean includeOptions)
    {
        if (onlyIds) {
            // 只返回题目基本信息，用于按需加载优化
            List<Map<String, Object>> questionBasics = mbtiTestService.getTestQuestionBasics(testTypeId);
            return success(questionBasics);
        } else {
            // 返回完整题目信息（兼容原有逻辑）
            List<Map<String, Object>> questions = mbtiTestService.getTestQuestions(testTypeId);
            return success(questions);
        }
    }

    /**
     * 获取单个题目详情
     */
    @GetMapping("/question/{questionId}")
    public AjaxResult getQuestionDetail(@PathVariable Long questionId)
    {
        Map<String, Object> question = mbtiTestService.getQuestionDetail(questionId);
        return success(question);
    }

    /**
     * 批量获取题目详情（用于优化网络请求）
     */
    @PostMapping("/questions/batch")
    public AjaxResult getQuestionsDetail(@RequestBody Map<String, Object> params)
    {
        @SuppressWarnings("unchecked")
        List<Long> questionIds = (List<Long>) params.get("questionIds");
        if (questionIds == null || questionIds.isEmpty()) {
            return error("题目ID列表不能为空");
        }
        
        List<Map<String, Object>> questions = mbtiTestService.getQuestionsDetail(questionIds);
        return success(questions);
    }

    /**
     * 预加载题目（智能预加载相邻题目）
     */
    @GetMapping("/preload")
    public AjaxResult preloadQuestions(
        @RequestParam Long testTypeId,
        @RequestParam Integer currentIndex,
        @RequestParam(defaultValue = "3") Integer range)
    {
        List<Map<String, Object>> questions = mbtiTestService.preloadQuestions(testTypeId, currentIndex, range);
        return success(questions);
    }

    /**
     * 提交单个题目答案
     */
    @Log(title = "MBTI测试答题", businessType = BusinessType.UPDATE)
    @PostMapping("/answer")
    public AjaxResult submitAnswer(@RequestBody Map<String, Object> params)
    {
        Long recordId = Long.valueOf(params.get("recordId").toString());
        Long questionId = Long.valueOf(params.get("questionId").toString());
        Long optionId = Long.valueOf(params.get("optionId").toString());
        
        boolean success = mbtiTestService.submitAnswer(recordId, questionId, optionId);
        if (success)
        {
            return success("答案提交成功");
        }
        else
        {
            return error("答案提交失败");
        }
    }

    /**
     * 批量提交答案
     */
    @Log(title = "MBTI测试批量答题", businessType = BusinessType.UPDATE)
    @PostMapping("/answers")
    public AjaxResult submitAnswers(@RequestBody Map<String, Object> params)
    {
        Long recordId = Long.valueOf(params.get("recordId").toString());
        @SuppressWarnings("unchecked")
        Map<String, Object> answersMap = (Map<String, Object>) params.get("answers");
        
        // 转换答案格式
        Map<Long, Long> answers = new java.util.HashMap<>();
        for (Map.Entry<String, Object> entry : answersMap.entrySet())
        {
            Long questionId = Long.valueOf(entry.getKey());
            Long optionId = Long.valueOf(entry.getValue().toString());
            answers.put(questionId, optionId);
        }
        
        boolean success = mbtiTestService.submitAnswers(recordId, answers);
        if (success)
        {
            return success("答案提交成功");
        }
        else
        {
            return error("答案提交失败");
        }
    }

    /**
     * 完成测试并获取结果
     */
    @Log(title = "MBTI测试完成", businessType = BusinessType.UPDATE)
    @PostMapping("/complete/{recordId}")
    public AjaxResult completeTest(@PathVariable Long recordId)
    {
        try
        {
            MbtiResult result = mbtiTestService.completeTest(recordId);
            return AjaxResult.success("测试完成", result);
        }
        catch (Exception e)
        {
            return error("测试完成失败：" + e.getMessage());
        }
    }

    /**
     * 获取测试结果详情（匿名访问支持）
     */
    @GetMapping("/result/{recordId}")
    public AjaxResult getTestResult(@PathVariable Long recordId)
    {
        try
        {
            Map<String, Object> result = mbtiTestService.getTestResult(recordId);
            return success(result);
        }
        catch (Exception e)
        {
            return error("获取测试结果失败：" + e.getMessage());
        }
    }

    /**
     * 获取人格类型详细描述
     */
    @GetMapping("/personality/{personalityType}")
    public AjaxResult getPersonalityTypeDescription(@PathVariable String personalityType)
    {
        MbtiPersonalityType description = mbtiTestService.getPersonalityTypeDescription(personalityType);
        if (description == null)
        {
            return error("人格类型不存在");
        }
        return success(description);
    }

    /**
     * 获取测试进度
     */
    @GetMapping("/progress/{recordId}")
    public AjaxResult getTestProgress(@PathVariable Long recordId)
    {
        try
        {
            Map<String, Object> progress = mbtiTestService.getTestProgress(recordId);
            return success(progress);
        }
        catch (Exception e)
        {
            return error("获取测试进度失败：" + e.getMessage());
        }
    }

    /**
     * 放弃测试
     */
    @Log(title = "MBTI测试放弃", businessType = BusinessType.UPDATE)
    @PostMapping("/abandon/{recordId}")
    public AjaxResult abandonTest(@PathVariable Long recordId)
    {
        boolean success = mbtiTestService.abandonTest(recordId);
        if (success)
        {
            return success("测试已放弃");
        }
        else
        {
            return error("放弃测试失败");
        }
    }

    /**
     * 获取用户测试历史（需要登录）
     */
    @PreAuthorize("@ss.hasPermi('mbti:test:history')")
    @GetMapping("/history")
    public AjaxResult getUserTestHistory()
    {
        try
        {
            Long userId = SecurityUtils.getUserId();
            List<Map<String, Object>> history = mbtiTestService.getUserTestHistory(userId);
            return success(history);
        }
        catch (Exception e)
        {
            return error("请先登录");
        }
    }

    /**
     * 获取MBTI统计数据
     */
    @PreAuthorize("@ss.hasPermi('mbti:test:statistics')")
    @GetMapping("/statistics")
    public AjaxResult getMbtiStatistics()
    {
        Map<String, Object> statistics = mbtiTestService.getMbtiStatistics();
        return success(statistics);
    }

    /**
     * 验证测试记录
     */
    @GetMapping("/validate/{recordId}")
    public AjaxResult validateTestRecord(@PathVariable Long recordId)
    {
        boolean valid = mbtiTestService.validateTestRecord(recordId);

        // 创建返回数据
        java.util.Map<String, Object> data = new java.util.HashMap<>();
        data.put("valid", valid);

        return AjaxResult.success("验证结果", data);
    }
}
